#pragma once

#include "Vector3D.h"
#include "Geometry.h"
#include "Ray.h"

class CKdTree
{
public:
	class CKdTreeNode
	{
	public:
		CKdTreeNode(int iAxis, int iLevel);
		virtual ~CKdTreeNode();

		void Build(const vector<CGeometryPtr>& vGeometries);
		void RayIntersection(const CRay& ray, vector<CGeometryPtr>& vGeometriesOut) const;

	private:
		void ComputeBestSplitPosition();
		bool IsIntersect(const CRay& ray) const;
		
		int m_iAxis;
		int m_iLevel;
		DATA_TYPE m_fSplitPosition;

	public:
		vector<CGeometryPtr> m_vGeometries;

		boost::shared_ptr<CKdTreeNode> m_spLeft;
		boost::shared_ptr<CKdTreeNode> m_spRight;

		CVector3D m_fRangeMin;
		CVector3D m_fRangeMax;
	};

	typedef boost::shared_ptr<CKdTreeNode> CKdTreeNodePtr;

	CKdTree(void);
	virtual ~CKdTree(void);

	void Build(const vector<CGeometryPtr>& vGeometries);
	void RayIntersection(const CRay& ray, vector<CGeometryPtr>& vGeometriesOut) const;

private:
	CKdTreeNodePtr m_spRoot;
};

